<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html><head> 
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>RESTful doctesting using app.request (web.py)</title> 
  <link rel="stylesheet" type="text/css" href="/static/webpy-new.css"/> 
  <link rel="SHORTCUT ICON" href="/static/favicon.ico"/> 
</head><body> 
 
        <div id="header"><table class="header"><tr>
                <td class="logo"><a href="/" title="Home"><img src="/static/webpy.gif" alt="" /></a></td> 
<td class="blurb">&ldquo;Think about the ideal way to write a web app.<br />Write the code to make it happen.&rdquo; [<a href="/philosophy">more...</a>]</td> </tr>
</table>
        </div> 
        <div id="location"> 
                <a href="/">home</a> &gt; RESTful doctesting using app.request
        </div> 
<div id="container"> 
<div id="sidebar">
<strong>get started:</strong>
<ul class="body">
  <li><a href="/install">install</a></li>
  <li><a href="/docs/0.3/tutorial">tutorial</a></li>
</ul>
<strong>learn more:</strong>
<ul class="body">
<li><a href="/docs/0.3/api">api reference</a></li>
<li><a href="/cookbook/">cookbook</a></li>
<li><a href="/src/">code examples</a></li>
</ul>

<strong>dive in:</strong>
<ul class="body"> 
<li><a href="https://github.com/webpy/webpy">source code</a></li>
<li><a href="http://groups.google.com/group/webpy/">mailing list</a></li>
<li><a href="https://github.com/webpy/webpy/issues">issue tracker</a></li>
</ul>
</div>

<div id="main"> 
<div id="content" class="body"> 
<h1>RESTful doctesting using app.request</h1>

<h1>!/usr/bin/env python</h1>

<pre><code>"""
RESTful web.py testing

usage: python webapp.py 8080 [--test]

&gt;&gt;&gt; req = app.request('/mathematicians', method='POST')
&gt;&gt;&gt; req.status
'400 Bad Request'

&gt;&gt;&gt; name = {'first': 'Beno\xc3\xaet', 'last': 'Mandelbrot'}
&gt;&gt;&gt; data = urllib.urlencode(name)
&gt;&gt;&gt; req = app.request('/mathematicians', method='POST', data=data)
&gt;&gt;&gt; req.status
'201 Created'
&gt;&gt;&gt; created_path = req.headers['Location']
&gt;&gt;&gt; created_path
'/mathematicians/b-mandelbrot'
&gt;&gt;&gt; fn = '&lt;h1 class=fn&gt;{0} {1}&lt;/h1&gt;'.format(name['first'], name['last'])
&gt;&gt;&gt; assert fn in app.request(created_path).data

"""

import doctest
import urllib
import sys

import web


paths = (
  '/mathematicians(/)?', 'Mathematicians',
  '/mathematicians/([a-z])-([a-z]{2,})', 'Mathematician'
)
app = web.application(paths, globals())

dbname = {True: 'test', False: 'production'}[sys.argv[-1] == '--test']
db = {} # db = web.database(..., db='math_{0}'.format(dbname))


class Mathematicians:

  def GET(self, slash=False):
    """list all mathematicians and form to create new one"""
    if slash:
        raise web.seeother('/mathematicians')
    mathematicians = db.items() # db.select(...)
    return web.template.Template("""$def with (mathematicians)
      &lt;!doctype html&gt;
      &lt;html&gt;
      &lt;head&gt;
        &lt;meta charset=utf-8&gt;
        &lt;title&gt;Mathematicians&lt;/title&gt;
      &lt;/head&gt;
      &lt;body&gt;
        &lt;h1&gt;Mathematicians&lt;/h1&gt;
        $if mathematicians:
          &lt;ul class=blogroll&gt;
            $for path, name in mathematicians:
              &lt;li class=vcard&gt;&lt;a class="fn url"
              href=/mathematicians/$path&gt;$name.first $name.last&lt;/a&gt;&lt;/li&gt;
          &lt;/ul&gt;
        &lt;form action=/mathematicians method=post&gt;
          &lt;label&gt;First &lt;input name=first type=text&gt;&lt;/label&gt;
          &lt;label&gt;Last &lt;input name=last type=text&gt;&lt;/label&gt;
          &lt;input type=submit value=Add&gt;
        &lt;/form&gt;
      &lt;/body&gt;
      &lt;/html&gt;""")(mathematicians)

  def POST(self, _):
    """create new mathematician"""
    name = web.input('first', 'last')
    key = '{0}-{1}'.format(name.first[0].lower(), name.last.lower())
    name.first, name.last = name.first.capitalize(), name.last.capitalize()
    db[key] = name # db.insert(...)
    path = '/mathematicians/{0}'.format(key)
    web.ctx.status = '201 Created'
    web.header('Location', path)
    return web.template.Template("""$def with (path, name)
      &lt;!doctype html&gt;
      &lt;html&gt;
      &lt;head&gt;
        &lt;meta charset=utf-8&gt;
        &lt;title&gt;Profile Created&lt;/title&gt;
      &lt;/head&gt;
      &lt;body&gt;
        &lt;p&gt;Profile created for &lt;a href=$path&gt;$name.first $name.last&lt;/a&gt;.&lt;/p&gt;
      &lt;/body&gt;
      &lt;/html&gt;""")(path, name)


class Mathematician:

  def GET(self, first_initial, last_name):
    """display mathematician"""
    key = '{0}-{1}'.format(first_initial, last_name)
    try:
        mathematician = db[key] # db.select(...)
    except KeyError:
        raise web.notfound()
    return web.template.Template("""$def with (name)
      &lt;!doctype html&gt;
      &lt;html&gt;
      &lt;head&gt;
        &lt;meta charset=utf-8&gt;
        &lt;title&gt;$name.first $name.last&lt;/title&gt;
      &lt;/head&gt;
      &lt;body class=vcard&gt;
        &lt;p&gt;&lt;a href=/mathematicians rel=up&gt;Mathematicians&lt;/a&gt; &amp;#x25B8;&lt;/p&gt;
        &lt;h1 class=fn&gt;$name.first $name.last&lt;/h1&gt;
      &lt;/body&gt;
      &lt;/html&gt;""")(mathematician)


if __name__ == "__main__":
  if sys.argv[-1] == '--test':
    doctest.testmod()
  else:
    app.run()
</code></pre>

<div style="clear: both;"></div> 
 
</div> 
 
</div> 
</div>
        <div id="footer"> 
    <p>started by <a style="color: gray;" href="http://www.aaronsw.com/">Aaron Swartz</a> (<a style="color: black;" href="mailto:webpy@aaronsw.com">webpy@aaronsw.com</a>)</p>

<p><a href="https://github.com/webpy/webpy.github.com/blob/master/cookbook/restful_doctesting_using_request.zh-cn.md">fork this page on GitHub</a></p>
</div> 
 
</body> 
</html> 
